package com.boot.mgt.service.impl

import com.alibaba.fastjson.JSON
import com.boot.config.ParamConfig
import com.boot.config.datasource.OracleDb
import com.boot.core.result.EChartsBar
import com.boot.core.result.EChartsPie
import com.boot.core.result.EChartsRadar
import com.boot.core.result.ResultTo
import com.boot.mgt.dao.oracle.OracleTAcdFileMapper
import com.boot.mgt.model.vo.VehicleTypeAmountVo
import com.boot.mgt.service.TaDocumentsService
import com.deepoove.poi.XWPFTemplate
import com.deepoove.poi.data.PictureRenderData
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.io.ClassPathResource
import org.springframework.stereotype.Service
import java.net.URLEncoder
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletResponse
import kotlin.collections.LinkedHashMap

@Service
class TaDocumentsImpl : TaDocumentsService {

    private val log: Logger = LoggerFactory.getLogger(this::class.java)

    @Autowired
    private lateinit var paramConfig: ParamConfig

    private fun getEchartsImage(optionJSONStr: String): ByteArray? {
        //val postForm = FormBody.Builder().add("data","{\"title\":{\"text\":\"ECharts 入門示例\"},\"animation\":false,\"tooltip\":{},\"legend\":{\"data\":[\"銷量\"]},\"xAxis\":{\"data\":[\"襯衫\",\"羊毛衫\",\"雪紡衫\",\"褲子\",\"高跟鞋\",\"襪子\"]},\"yAxis\":{},\"series\":[{\"name\":\"銷量\",\"type\":\"bar\",\"data\":[5,20,36,10,10,20]}]}").build()
        val postForm = FormBody.Builder().add("data", optionJSONStr).build()

        log.info("echarts options->" + optionJSONStr)

        val client = OkHttpClient()
        val request = Request.Builder()
                .url(paramConfig.documents.echartsURL)
                .post(postForm).build()
        val response = client.newCall(request).execute()
        if (response.isSuccessful) {
            return response.body()?.bytes()
        } else {

        }

        return null
    }

    private fun insertLinkbreakForEcharts(originalStr: String): String {
        val linkbreakStep = 8
        val tempStr = StringBuilder(originalStr)
        val insertCounter = originalStr.length / linkbreakStep
        for (i in 1..insertCounter) {
            var index = i * 8 + i - 1
            tempStr.insert(index, '\n')
        }
        return tempStr.toString()
    }

    private fun getMonthList(beginDate: String, endDate: String): List<String> {
        var format = SimpleDateFormat("yyyy-MM-dd")
        var d1 = SimpleDateFormat("yyyy-MM-dd").parse(beginDate)
        var d2 = SimpleDateFormat("yyyy-MM-dd").parse(endDate)
        var dd = Calendar.getInstance()
        dd.time = d1

        var monthList = mutableListOf<String>()

        while (dd.time.before(d2)) {
            var sdf = SimpleDateFormat("yyyy-MM");
            log.info(sdf.format(dd.time))
            monthList.add(sdf.format(dd.time))
            dd.add(Calendar.MONTH, 1)
        }

        return monthList
    }

    @Autowired
    private lateinit var tAcdFileMapper: OracleTAcdFileMapper

    data class accidentData(val accidentAmountMonthList: LinkedHashMap<String, Int>,
                            val injuredAmountMonthList: LinkedHashMap<String, Int>,
                            val deathAmountMonthList: LinkedHashMap<String, Int>,
                            val accidentAmountAll: Int,
                            val injuredAmountAll: Int,
                            val deathAmountAll: Int)

    private fun getAccidentData(beginDate: String, endDate: String): accidentData {

        var month12 = getMonthList(beginDate, endDate)

        var flag: Boolean

        val accidentMonth = linkedMapOf<String, Int>()
        val deathMonth = linkedMapOf<String, Int>()
        val injuredMonth = linkedMapOf<String, Int>()

        val countMonthList = tAcdFileMapper.selectAccidentCountGroup(0, 100, 12, "'yyyy-MM'", paramConfig.documents.acdFileTableName)

        var totalAccidentAmount = 0
        var totalInjuredAmount = 0
        var totalDeathAmount = 0

        for (s in month12) {
            flag = false
            for (statisticsCountVo in countMonthList) {
                if (s == statisticsCountVo.dateStr) {
                    flag = true
                    accidentMonth[s] = statisticsCountVo.accidentsCount ?: 0
                    deathMonth[s] = statisticsCountVo.deathCount ?: 0
                    injuredMonth[s] = statisticsCountVo.injuredCount ?: 0

                    totalAccidentAmount += statisticsCountVo.accidentsCount ?: 0
                    totalInjuredAmount += statisticsCountVo.injuredCount ?: 0
                    totalDeathAmount += statisticsCountVo.deathCount ?: 0

                    continue
                }
            }
            if (!flag) {
                accidentMonth[s] = 0
                deathMonth[s] = 0
                injuredMonth[s] = 0
            }
        }

        return accidentData(accidentMonth, injuredMonth, deathMonth, totalAccidentAmount, totalInjuredAmount, totalDeathAmount)
    }

    private fun getAccidentEchartsOptionJSON(accidentAllData: accidentData): String {

        val accidentMonth = accidentAllData.accidentAmountMonthList
        val injuredMonth = accidentAllData.injuredAmountMonthList
        val deathMonth = accidentAllData.deathAmountMonthList


        var echartsBar = EChartsBar(
                color = listOf("#006699", "#4cabce", "#e5323e"),
                legend = EChartsBar.Legend(data = listOf("事故数", "受伤人数", "死亡人数")),
                title = EChartsBar.Title(text = "事故数"))

        var echartsOptionMap = mutableMapOf<String, Any>()

        echartsOptionMap["title"] = mapOf(Pair("text", "事故数"))
        echartsOptionMap["color"] = listOf("#006699", "#4cabce", "#e5323e")
        echartsOptionMap["animation"] = false
        echartsOptionMap["legend"] = mapOf(Pair("data", listOf("事故数", "受伤人数", "死亡人数")))


        echartsBar.yAxis.add(EChartsBar.YAxi(type = "value"))

        var accidentSeriesDataList = mutableListOf<Int>()
        var echartsXAxisList = mutableListOf<String>()

        for ((key, value) in accidentMonth) {
            echartsXAxisList.add(key)
            accidentSeriesDataList.add(value)
        }
        echartsBar.xAxis.add(EChartsBar.XAxi(data = echartsXAxisList, type = "category"))


        echartsBar.series.add(EChartsBar.SeriesItem(data = accidentSeriesDataList, name = "事故数", type = "bar"))

        var injuredSeriesDataList = mutableListOf<Int>()
        for ((_, value) in injuredMonth) {
            injuredSeriesDataList.add(value)
        }
        echartsBar.series.add(EChartsBar.SeriesItem(data = injuredSeriesDataList, name = "受伤人数", type = "bar"))


        var deathSeriesDataList = mutableListOf<Int>()
        for ((_, value) in deathMonth) {
            deathSeriesDataList.add(value)
        }
        echartsBar.series.add(EChartsBar.SeriesItem(data = deathSeriesDataList, name = "死亡人数", type = "bar"))


        log.info(JSON.toJSONString(echartsBar))
        return JSON.toJSONString(echartsBar)
    }



    @OracleDb
    override fun testFun(response: HttpServletResponse) {
        //getAccidentEchartsOptionJSON()
        val vdata = loadTopCauseAccidentDeathData("2017-01-01", "2018-01-01")

        //val vdatat =loadTopTQData("2017-01-01", "2018-01-01")


        response.outputStream.close()
    }
    /*
    违法行为-事故数-死亡人数top10
    */
    data class topCauseAccidentDeathData(val accidentEchartsOptionJSON: String, val deathEchartsOptionJSON:String, val causeAccidentDeathOutputList: List<String>)
    private fun loadTopCauseAccidentDeathData(beginDate: String, endDate: String): topCauseAccidentDeathData{
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val limitAmount = 10
        var dbAmountList = tAcdFileMapper.selectAccidentCauseDeathAmountGroup(acdTableName, codeTableName, beginDateStr, endDateStr, limitAmount)
        var docOutputList = mutableListOf<String>()

        var echartsPieAccident = EChartsPie(
                title = EChartsPie.Title(text = "TOP违法行为-事故数", x = "center")
        )

        var echartsPieDeath = EChartsPie(
                title = EChartsPie.Title(text = "TOP违法行为-死亡人数", x = "center")
        )
        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        var seriesDataMapAccident = linkedMapOf<String, Int>()
        var seriesDataMapDeath = linkedMapOf<String, Int>()

        for (vo in dbAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }

        for (vo in dbAmountList) {
            var currentDataName = ""

            currentDataName = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())
            seriesDataMapAccident[currentDataName] = vo.accidentAmount!!

            currentDataName = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())
            seriesDataMapDeath[currentDataName] = vo.deathAmount!!

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)

            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()
            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            docOutputList.add(currentOutputContent)
        }

        var accidentSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()
        var deathSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()

        for ((key, value) in seriesDataMapAccident) {
            accidentSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key),value = value))
        }

        for ((key, value) in seriesDataMapDeath){
            deathSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key), value = value))
        }

        echartsPieAccident.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = accidentSeriesDataList, name="车辆类型比率"))
        echartsPieDeath.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = deathSeriesDataList, name ="车辆类型比率"))

        log.info(JSON.toJSONString(echartsPieAccident))
        log.info(JSON.toJSONString(echartsPieDeath))


        return topCauseAccidentDeathData(JSON.toJSONString(echartsPieAccident), JSON.toJSONString(echartsPieDeath), docOutputList)
    }

    /*
    车辆使用性质top10
    */
    data class topCLSYXZTypeData(val echartsOptionJSON: String, val clsyxzOutputList:List<String>)
    private fun loadTopCLSYXZData(beginDate: String, endDate: String): topCLSYXZTypeData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 10
        var clsyxzAmountList = tAcdFileMapper.selectAccidentCLSYXZAmountGroup(acdTableName, codeTableName, acdFileHumanTableName, beginDateStr, endDateStr, limitAmount)
        var clsyxzOutputList = mutableListOf<String>()


        var echartsRadar = EChartsRadar(
                title = EChartsRadar.Title(text = "TOP车辆使用性质-事故数-死亡人数"),
                legend = EChartsRadar.Legend(data = mutableListOf("事故数", "死亡人数"))
        )

        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        val maxCauseAccidentAmount = clsyxzAmountList[0].accidentAmount
        var preEchartsDataMap = linkedMapOf<String, Int>()

        for (vo in clsyxzAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }
        log.info("totalAmount is ->" + totalAccidentAmount.toString())

        var seriesAccidentAmountData = EChartsRadar.SeriesItem.Data(name = "事故数")
        var seriesDeathAmountData = EChartsRadar.SeriesItem.Data(name = "死亡人数")

        for (vo in clsyxzAmountList) {
            //echarts部分
            var currentDataName = "%s的事故数：%d，死亡人数：%d".format(vo.description, vo.accidentAmount, vo.deathAmount)
            preEchartsDataMap[currentDataName] = -1

            seriesAccidentAmountData.value.add(vo.accidentAmount!!)
            seriesDeathAmountData.value.add(vo.deathAmount!!)

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)
            log.info("currentDeathAmount->" + vo.deathAmount)

            //文字描述部分
            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()
            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            clsyxzOutputList.add(currentOutputContent)

        }

        echartsRadar.series.add(EChartsRadar.SeriesItem(data = mutableListOf(seriesAccidentAmountData, seriesDeathAmountData)))

        log.info("preEchartsDataMap->" + preEchartsDataMap.toString())

        var radarListNew = mutableListOf<EChartsRadar.Radar>()
        var radarListIndicator = mutableListOf<EChartsRadar.Radar.Indicator>()

        for ((key, value) in preEchartsDataMap) {

            radarListIndicator.add(EChartsRadar.Radar.Indicator(max = maxCauseAccidentAmount!!, text = insertLinkbreakForEcharts(key)))
        }
        radarListNew.add(EChartsRadar.Radar(indicator = radarListIndicator))

        echartsRadar.radar = radarListNew

        log.info(JSON.toJSONString(echartsRadar))

        return topCLSYXZTypeData(JSON.toJSONString(echartsRadar), clsyxzOutputList)
    }


    /*
    天气top10
    */
    data class topTQTypeData(val accidentEchartsOptionJSON: String,val deathEchartsOptionJSON: String, val TQOutputList:List<String>)
    private fun loadTopTQData(beginDate: String, endDate: String): topTQTypeData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 10
        var dbAmountList = tAcdFileMapper.selectAccidentTQAmountGroup(acdTableName, codeTableName, beginDateStr, endDateStr, limitAmount)
        var docOutputList = mutableListOf<String>()
        var echartsPieAccident = EChartsPie(
                title = EChartsPie.Title(text = "TOP天气-事故数", x = "center")
        )

        var echartsPieDeath = EChartsPie(
                title = EChartsPie.Title(text = "TOP天气-死亡人数", x = "center")
        )

        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        var seriesDataMapAccident = linkedMapOf<String, Int>()
        var seriesDataMapDeath = linkedMapOf<String, Int>()

        for (vo in dbAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }

        for (vo in dbAmountList) {
            var currentDataName: String = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())

            seriesDataMapAccident[currentDataName] = vo.accidentAmount!!

            currentDataName = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())
            seriesDataMapDeath[currentDataName] = vo.deathAmount!!

            log.info("currentDataName->$currentDataName")
            log.info("currentCaseAmount->" + vo.accidentAmount)

            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()
            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            docOutputList.add(currentOutputContent)
        }

        var accidentSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()
        var deathSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()

        for ((key, value) in seriesDataMapAccident) {
            accidentSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key),value = value))
        }

        for ((key, value) in seriesDataMapDeath){
            deathSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key), value = value))
        }

        echartsPieAccident.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = accidentSeriesDataList, name="车辆类型比率"))
        echartsPieDeath.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = deathSeriesDataList, name ="车辆类型比率"))

        log.info(JSON.toJSONString(echartsPieAccident))
        log.info(JSON.toJSONString(echartsPieDeath))

        return topTQTypeData(JSON.toJSONString(echartsPieAccident), JSON.toJSONString(echartsPieDeath), docOutputList)
    }

    /*
    24小时内各小时的事故数、死亡人数
    */
    data class HoursData(val echartsOptionJSON: String, val HoursOutputList:List<String>)
    private fun loadHoursData(beginDate: String, endDate: String): HoursData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        var HoursAmountList = tAcdFileMapper.selectAccidentHoursAmountGroup(acdTableName, beginDateStr, endDateStr)
        var HoursOutputList = mutableListOf<String>()

        var echartsRadar = EChartsRadar(
                title = EChartsRadar.Title(text = "TOP小时-事故数-死亡人数"),
                legend = EChartsRadar.Legend(data = mutableListOf("事故数", "死亡人数"))
        )

        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        val maxCauseAccidentAmount = HoursAmountList[0].accidentAmount
        var preEchartsDataMap = linkedMapOf<String, Int>()

        for (vo in HoursAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }
        log.info("totalAmount is ->" + totalAccidentAmount.toString())

        var seriesAccidentAmountData = EChartsRadar.SeriesItem.Data(name = "事故数")
        var seriesDeathAmountData = EChartsRadar.SeriesItem.Data(name = "死亡人数")

        for (vo in HoursAmountList) {
            //echarts部分
            var currentDataName = "%s的事故数：%d，死亡人数：%d".format(vo.description, vo.accidentAmount, vo.deathAmount)
            preEchartsDataMap[currentDataName] = -1

            seriesAccidentAmountData.value.add(vo.accidentAmount!!)
            seriesDeathAmountData.value.add(vo.deathAmount!!)

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)
            log.info("currentDeathAmount->" + vo.deathAmount)

            //文字描述部分
            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()
            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            HoursOutputList.add(currentOutputContent)

        }

        echartsRadar.series.add(EChartsRadar.SeriesItem(data = mutableListOf(seriesAccidentAmountData, seriesDeathAmountData)))

        log.info("preEchartsDataMap->" + preEchartsDataMap.toString())

        var radarListNew = mutableListOf<EChartsRadar.Radar>()
        var radarListIndicator = mutableListOf<EChartsRadar.Radar.Indicator>()

        for ((key, value) in preEchartsDataMap) {

            radarListIndicator.add(EChartsRadar.Radar.Indicator(max = maxCauseAccidentAmount!!, text = insertLinkbreakForEcharts(key)))
        }
        radarListNew.add(EChartsRadar.Radar(indicator = radarListIndicator))

        echartsRadar.radar = radarListNew

        log.info(JSON.toJSONString(echartsRadar))
        return HoursData(JSON.toJSONString(echartsRadar), HoursOutputList)
    }

    /*
道路类型事故数、死亡人数
*/
    data class DLLXData(val echartsOptionJSON: String, val docOutputList:List<String>)
    private fun loadDLLXData(beginDate: String, endDate: String): DLLXData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val limitAmount = 20
        var dbAmountList = tAcdFileMapper.selectAccidentDLLXAmountGroup(acdTableName,codeTableName, beginDateStr, endDateStr, limitAmount)
        var docOutputList = mutableListOf<String>()

        var echartsRadar = EChartsRadar(
                title = EChartsRadar.Title(text = "TOP道路类型-事故数-死亡人数"),
                legend = EChartsRadar.Legend(data = mutableListOf("事故数", "死亡人数"))
        )

        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        val maxCauseAccidentAmount = dbAmountList[0].accidentAmount
        var preEchartsDataMap = linkedMapOf<String, Int>()

        for (vo in dbAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }
        log.info("totalAmount is ->" + totalAccidentAmount.toString())

        var seriesAccidentAmountData = EChartsRadar.SeriesItem.Data(name = "事故数")
        var seriesDeathAmountData = EChartsRadar.SeriesItem.Data(name = "死亡人数")

        for (vo in dbAmountList) {
            //echarts部分
            var currentDataName = "%s的事故数：%d，死亡人数：%d".format(vo.description, vo.accidentAmount, vo.deathAmount)
            preEchartsDataMap[currentDataName] = -1

            //seriesAccidentAmountData.value.add(vo.accidentAmount!!)
            //seriesDeathAmountData.value.add(vo.deathAmount!!)

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)
            log.info("currentDeathAmount->" + vo.deathAmount)

            //文字描述部分
            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()

            seriesAccidentAmountData.value.add(percentageOfAccident)
            seriesDeathAmountData.value.add(percentageOfDeath)

            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            docOutputList.add(currentOutputContent)

        }

        echartsRadar.series.add(EChartsRadar.SeriesItem(data = mutableListOf(seriesAccidentAmountData, seriesDeathAmountData)))

        log.info("preEchartsDataMap->" + preEchartsDataMap.toString())

        var radarListNew = mutableListOf<EChartsRadar.Radar>()
        var radarListIndicator = mutableListOf<EChartsRadar.Radar.Indicator>()

        for ((key, value) in preEchartsDataMap) {

            radarListIndicator.add(EChartsRadar.Radar.Indicator(max = maxCauseAccidentAmount!!, text = insertLinkbreakForEcharts(key)))
        }
        radarListNew.add(EChartsRadar.Radar(indicator = radarListIndicator))

        echartsRadar.radar = radarListNew

        log.info(JSON.toJSONString(echartsRadar))
        return DLLXData(JSON.toJSONString(echartsRadar), docOutputList)
    }

    data class topVehicleTypeData(val echartsOptionJSON: String, val vehicleTypeAmountList: List<VehicleTypeAmountVo>)

    private fun loadTopVehicleTypeDate(beginDate: String, endDate: String): topVehicleTypeData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 10

        var echartsPie = EChartsPie(
                title = EChartsPie.Title(text = "TOP车辆类型", x = "center")
        )

        var causeAmountList = tAcdFileMapper.selectVehicleTypeAmountGroup(acdTableName, codeTableName, acdFileHumanTableName, beginDateStr, endDateStr, limitAmount)

        var echartsOptionMap = mutableMapOf<String, Any>()
        echartsOptionMap["title"] = mapOf(Pair("text", "TOP车辆类型"), Pair("x", "center"))
        echartsOptionMap["tooltip"] = mapOf(Pair("trigger", "item"), Pair("formatter", "{a} <br/>{b} : {c} ({d}%)"))

        var totalAmount = 0
        var preEchartsDataMap = linkedMapOf<String, Int>()

        for (vo in causeAmountList) {
            totalAmount += vo.accidentAmount!!
        }
        log.info("totalAmount is ->" + totalAmount.toString())

        var currentDataName = ""
        for (vo in causeAmountList) {
            var percentage = ((vo.accidentAmount!!.toFloat() / totalAmount.toFloat()) * 100).toInt()
            currentDataName = "%s:%d%%".format(vo.description, percentage)
            preEchartsDataMap[currentDataName] = vo.accidentAmount!!

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)
        }

        log.info("preEchartsDataMap->" + preEchartsDataMap.toString())

        var seriesDataListNew = mutableListOf<EChartsPie.SeriesItem.Data>()

        for ((key, value) in preEchartsDataMap) {
            seriesDataListNew.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key),value = value))
        }

        echartsPie.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = seriesDataListNew, name="车辆类型比率"))

        log.info(JSON.toJSONString(echartsPie))

        return topVehicleTypeData(JSON.toJSONString(echartsPie), causeAmountList)
    }

    /*事故形态事故数、死亡人数*/
    data class SGXTData( val accidentEchartsOptionJSON: String,val deathEchartsOptionJSON: String, val SGXTOutputList:List<String>)
    private fun loadSGXTData(beginDate: String, endDate: String): SGXTData {
        val beginDateStr = beginDate
        val endDateStr = endDate
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 10

        var echartsPieAccident = EChartsPie(
                title = EChartsPie.Title(text = "TOP事故形态-事故数", x = "center")
        )

        var echartsPieDeath = EChartsPie(
                title = EChartsPie.Title(text = "TOP事故形态-死亡人数", x = "center")
        )

        var dbAmountList = tAcdFileMapper.selectAccidentSGXTAmountGroup(acdTableName, codeTableName, beginDateStr, endDateStr, limitAmount)

        var docOutputList = mutableListOf<String>()

        var totalAccidentAmount = 0
        var totalDeathAmount = 0
        var seriesDataMapAccident = linkedMapOf<String, Int>()
        var seriesDataMapDeath = linkedMapOf<String, Int>()

        for (vo in dbAmountList) {
            totalAccidentAmount += vo.accidentAmount!!
            totalDeathAmount += vo.deathAmount!!
        }

        for (vo in dbAmountList) {
            var currentDataName = ""

            currentDataName = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())
            seriesDataMapAccident[currentDataName] = vo.accidentAmount!!

            currentDataName = "%s:%d%%".format(vo.description,  ((vo.accidentAmount!!.toFloat() / totalAccidentAmount.toFloat()) * 100).toInt())
            seriesDataMapDeath[currentDataName] = vo.deathAmount!!

            log.info("currentDataName->" + currentDataName)
            log.info("currentCaseAmount->" + vo.accidentAmount)

            var percentageOfAccident = ((vo.accidentAmount!! / totalAccidentAmount.toFloat()) * 100).toInt()
            var percentageOfDeath = ((vo.deathAmount!! / totalDeathAmount.toFloat()) * 100).toInt()
            var currentOutputContent = "%s的事故数：%d（%d%%），死亡人数：%d（%d%%）".format(vo.description, vo.accidentAmount, percentageOfAccident, vo.deathAmount, percentageOfDeath)
            docOutputList.add(currentOutputContent)
        }

        var accidentSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()
        var deathSeriesDataList = mutableListOf<EChartsPie.SeriesItem.Data>()

        for ((key, value) in seriesDataMapAccident) {
            accidentSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key),value = value))
        }

        for ((key, value) in seriesDataMapDeath){
            deathSeriesDataList.add(EChartsPie.SeriesItem.Data(name = insertLinkbreakForEcharts(key), value = value))
        }

        echartsPieAccident.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = accidentSeriesDataList, name="车辆类型比率"))
        echartsPieDeath.series.add(EChartsPie.SeriesItem(center = listOf("50%", "60%"), data = deathSeriesDataList, name ="车辆类型比率"))

        log.info(JSON.toJSONString(echartsPieAccident))
        log.info(JSON.toJSONString(echartsPieDeath))
        return SGXTData(JSON.toJSONString(echartsPieAccident) ,JSON.toJSONString(echartsPieDeath), docOutputList)
    }

    @OracleDb
    override fun export(beginDate: String, endDate: String, response: HttpServletResponse) {

        val outputFileName = "交通事故统计报告（$beginDate-$endDate）"
        var outputFileNameEncoded = URLEncoder.encode(outputFileName, "UTF-8") + ".docx"

        //top10 事故原因
        /*
        val topCauseData = loadTopCauseDate(beginDate, endDate)
        val topCauseEchartsOptionJson = topCauseData.echartsOptionJSON
        val topCauseImageByteArray = getEchartsImage(topCauseEchartsOptionJson)
        val topCauseDiscription = topCauseData.causeAmountList[0].description!!
        */

        //违法行为-事故数-死亡人数top10
        val topCauseAccidentDeathData = loadTopCauseAccidentDeathData(beginDate, endDate)
        var causeAccidentDeathSummary = ""
        topCauseAccidentDeathData.causeAccidentDeathOutputList.forEach {
            causeAccidentDeathSummary = causeAccidentDeathSummary + it + "\n"
        }
        val topCauseAccidentImageByteArray = getEchartsImage(topCauseAccidentDeathData.accidentEchartsOptionJSON)
        val topCauseDeathImageByteArray = getEchartsImage(topCauseAccidentDeathData.deathEchartsOptionJSON)



        //车辆使用性质-事故数-死亡人数top10
        val topCLSYXZAccidentDeathData = loadTopCLSYXZData(beginDate, endDate)
        var clsyxzAccidentDeathSummary = ""
        for (content in topCLSYXZAccidentDeathData.clsyxzOutputList){
            clsyxzAccidentDeathSummary = clsyxzAccidentDeathSummary + content + "\n"
        }
        val topCLSYXZDeathImageByteArray = getEchartsImage(topCLSYXZAccidentDeathData.echartsOptionJSON)

        //天气
        val topTQAccidentDeathData = loadTopTQData(beginDate, endDate)
        var tqAccidentDeathSummary = ""
        topTQAccidentDeathData.TQOutputList.forEach {
            tqAccidentDeathSummary = tqAccidentDeathSummary + it + "\n"
        }
        val topTQAccidentImageByteArray = getEchartsImage(topTQAccidentDeathData.accidentEchartsOptionJSON)
        val topTQDeathImageByteArray = getEchartsImage(topTQAccidentDeathData.deathEchartsOptionJSON)

        //24h-事故数-死亡人数top10
        val topHoursAccidentDeathData = loadHoursData(beginDate, endDate)
        var hoursAccidentDeathSummary = ""
        for (content in topHoursAccidentDeathData.HoursOutputList){
            hoursAccidentDeathSummary = hoursAccidentDeathSummary + content + "\n"
        }
        val topHoursDeathImageByteArray = getEchartsImage(topHoursAccidentDeathData.echartsOptionJSON)


        //道路类型-事故数-死亡人数top10
        val dllxAccidentDeathData = loadDLLXData(beginDate, endDate)
        var dllxAccidentDeathSummary = ""
        for (content in dllxAccidentDeathData.docOutputList){
            dllxAccidentDeathSummary = dllxAccidentDeathSummary + content + "\n"
        }
        val dllxAccidentDeathImageByteArray = getEchartsImage(dllxAccidentDeathData.echartsOptionJSON)

        //top10 车辆类型
        val topVehicleTypeData = loadTopVehicleTypeDate(beginDate, endDate)
        val topVehicleTypeEchartsOptionJson = topVehicleTypeData.echartsOptionJSON
        val topVehicleTypeImageByteArray = getEchartsImage(topVehicleTypeEchartsOptionJson)
        val topVehicleTypeDiscription = topVehicleTypeData.vehicleTypeAmountList[0].description!!


        //top10 事故形态

        val topSGXTAccidentDeathData = loadSGXTData(beginDate, endDate)
        var sgxtAccidentDeathSummary = ""
        topSGXTAccidentDeathData.SGXTOutputList.forEach {
            sgxtAccidentDeathSummary = sgxtAccidentDeathSummary + it + "\n"
        }
        val topSGXTAccidentImageByteArray = getEchartsImage(topSGXTAccidentDeathData.accidentEchartsOptionJSON)
        val topSGXTDeathImageByteArray = getEchartsImage(topSGXTAccidentDeathData.deathEchartsOptionJSON)

        //事故数量，受伤，死亡人数统计
        val accidentAllData = getAccidentData(beginDate, endDate)
        val optionJSONStrTmp = getAccidentEchartsOptionJSON(accidentAllData)
        val accidentBarImageByteArray = getEchartsImage(optionJSONStrTmp)


        //pot-tl 模板渲染
        val cpr = ClassPathResource("export_templates/template.docx")

        val template = XWPFTemplate.compile(cpr.inputStream).render(object : HashMap<String, Any>() {
            init {
                put("title", "交通事故统计报告")
                put("beginDate", beginDate)
                put("endDate", endDate)
                put("accidentAmount", accidentAllData.accidentAmountAll)
                put("injuredAmount", accidentAllData.injuredAmountAll)
                put("deathAmount", accidentAllData.deathAmountAll)
                put("accidentBarImage", PictureRenderData(600, 600, ".png", accidentBarImageByteArray))

                //违法行为-事故数-死亡人数top10
                put("topCauseAccidentPieImage", PictureRenderData(600, 600, ".png", topCauseAccidentImageByteArray))
                put("topCauseDeathPieImage", PictureRenderData(600, 600, ".png", topCauseDeathImageByteArray))
                put("causeAccidentDeathSummary", causeAccidentDeathSummary)

                //车辆使用性质-事故数-死亡人数top10
                put("topCLSYXZAccidentDeathRadarImage", PictureRenderData(600, 600, ".png", topCLSYXZDeathImageByteArray))
                put("clsyxzAccidentDeathSummary", clsyxzAccidentDeathSummary)

                //天气-事故数-死亡人数top10
                put("topTQAccidentPieImage", PictureRenderData(600, 600, ".png", topTQAccidentImageByteArray))
                put("topTQDeathPieImage", PictureRenderData(600, 600, ".png", topTQDeathImageByteArray))
                put("tqAccidentDeathSummary", tqAccidentDeathSummary)

                //24h-事故数-死亡人数top10
                put("topHoursAccidentDeathRadarImage", PictureRenderData(600, 600, ".png", topHoursDeathImageByteArray))
                put("hoursAccidentDeathSummary", hoursAccidentDeathSummary)

                //道路类型-事故数-死亡人数top10
                put("topDLLXAccidentDeathRadarImage", PictureRenderData(600, 600, ".png", dllxAccidentDeathImageByteArray))
                put("dllxAccidentDeathSummary", dllxAccidentDeathSummary)

                //车辆类型-事故数
                put("topVehicleTypePieImage", PictureRenderData(600, 600, ".png", topVehicleTypeImageByteArray))
                put("top1VehicleTypeDescription", topVehicleTypeDiscription)

                //事故形态-事故数-死亡人数top10
                put("topSGXTAccidentPieImage", PictureRenderData(600, 600, ".png", topSGXTAccidentImageByteArray))
                put("topSGXTDeathPieImage", PictureRenderData(600, 600, ".png", topSGXTDeathImageByteArray))
                put("sgxtAccidentDeathSummary", sgxtAccidentDeathSummary)
            }
        })
        response.characterEncoding = "UTF-8"
        response.contentType = "application/x-download"
        response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
        response.setHeader("Content-Disposition",
                "attachment;filename=$outputFileNameEncoded")
        template.write(response.outputStream)
        response.outputStream.close()
    }

    @OracleDb
    override fun getTQChartsData(beginDate: String, endDate: String, response: HttpServletResponse):ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 10
        var TQAmountList = tAcdFileMapper.selectAccidentTQAmountGroup(acdTableName, codeTableName, beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }

    @OracleDb
    override fun getHoursChartsData(beginDate: String, endDate: String, response: HttpServletResponse):ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        var TQAmountList = tAcdFileMapper.selectAccidentHoursAmountGroup(acdTableName, beginDate, endDate)
        return ResultTo().setData("charts_data", TQAmountList)
    }

    @OracleDb
    override fun getSGXTChartsData(beginDate: String, endDate: String, response: HttpServletResponse):ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val limitAmount = 20
        var TQAmountList = tAcdFileMapper.selectAccidentSGXTAmountGroup(acdTableName, codeTableName, beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }

    @OracleDb
    override fun getCLSYXZChartsData(beginDate: String, endDate: String, response: HttpServletResponse): ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 20
        var TQAmountList = tAcdFileMapper.selectAccidentCLSYXZAmountGroup(acdTableName, codeTableName, acdFileHumanTableName, beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }

    @OracleDb
    override fun getDLLXChartsData(beginDate: String, endDate: String, response: HttpServletResponse): ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 20
        var TQAmountList = tAcdFileMapper.selectAccidentDLLXAmountGroup(acdTableName, codeTableName,  beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }
    @OracleDb
    override fun getCauseChartsData(beginDate: String, endDate: String, response: HttpServletResponse): ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val limitAmount = 20
        var TQAmountList = tAcdFileMapper.selectAccidentCauseDeathAmountGroup(acdTableName, codeTableName,  beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }

    @OracleDb
    override fun getVehicleTypeChartsData(beginDate: String, endDate: String, response: HttpServletResponse): ResultTo {
        val acdTableName = paramConfig.documents.acdFileTableName
        val codeTableName = paramConfig.documents.codeTableName
        val acdFileHumanTableName = paramConfig.documents.acdHumanTableName
        val limitAmount = 20
        var TQAmountList = tAcdFileMapper.selectVehicleTypeAmountGroup(acdTableName, codeTableName ,acdFileHumanTableName,  beginDate, endDate, limitAmount)
        return ResultTo().setData("charts_data", TQAmountList)
    }

}